﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using WordNet.Core.ElementContracts;

namespace WordNet.Core
{
    public class VerbFrame: IVerbFrame
    {
        public static readonly VerbFrame NUM_01 = new VerbFrame(1, "Something ----s");
        public static readonly VerbFrame NUM_02 = new VerbFrame(2, "Somebody ----s");
        public static readonly VerbFrame NUM_03 = new VerbFrame(3, "It is ----ing");
        public static readonly VerbFrame NUM_04 = new VerbFrame(4, "Something is ----ing PP");
        public static readonly VerbFrame NUM_05 = new VerbFrame(5, "Something ----s something Adjective/Noun");
        public static readonly VerbFrame NUM_06 = new VerbFrame(6, "Something ----s Adjective/Noun");
        public static readonly VerbFrame NUM_07 = new VerbFrame(7, "Somebody ----s Adjective");
        public static readonly VerbFrame NUM_08 = new VerbFrame(8, "Somebody ----s something");
        public static readonly VerbFrame NUM_09 = new VerbFrame(9, "Somebody ----s somebody");
        public static readonly VerbFrame NUM_10 = new VerbFrame(10, "Something ----s somebody");
        public static readonly VerbFrame NUM_11 = new VerbFrame(11, "Something ----s something");
        public static readonly VerbFrame NUM_12 = new VerbFrame(12, "Something ----s to somebody");
        public static readonly VerbFrame NUM_13 = new VerbFrame(13, "Somebody ----s on something");
        public static readonly VerbFrame NUM_14 = new VerbFrame(14, "Somebody ----s somebody something");
        public static readonly VerbFrame NUM_15 = new VerbFrame(15, "Somebody ----s something to somebody");
        public static readonly VerbFrame NUM_16 = new VerbFrame(16, "Somebody ----s something from somebody");
        public static readonly VerbFrame NUM_17 = new VerbFrame(17, "Somebody ----s somebody with something");
        public static readonly VerbFrame NUM_18 = new VerbFrame(18, "Somebody ----s somebody of something");
        public static readonly VerbFrame NUM_19 = new VerbFrame(19, "Somebody ----s something on somebody");
        public static readonly VerbFrame NUM_20 = new VerbFrame(20, "Somebody ----s somebody PP");
        public static readonly VerbFrame NUM_21 = new VerbFrame(21, "Somebody ----s something PP");
        public static readonly VerbFrame NUM_22 = new VerbFrame(22, "Somebody ----s PP");
        public static readonly VerbFrame NUM_23 = new VerbFrame(23, "Somebody's (body part) ----s");
        public static readonly VerbFrame NUM_24 = new VerbFrame(24, "Somebody ----s somebody to INFINITIVE");
        public static readonly VerbFrame NUM_25 = new VerbFrame(25, "Somebody ----s somebody INFINITIVE");
        public static readonly VerbFrame NUM_26 = new VerbFrame(26, "Somebody ----s that CLAUSE");
        public static readonly VerbFrame NUM_27 = new VerbFrame(27, "Somebody ----s to somebody");
        public static readonly VerbFrame NUM_28 = new VerbFrame(28, "Somebody ----s to INFINITIVE");
        public static readonly VerbFrame NUM_29 = new VerbFrame(29, "Somebody ----s whether INFINITIVE");
        public static readonly VerbFrame NUM_30 = new VerbFrame(30, "Somebody ----s somebody into V-ing something");
        public static readonly VerbFrame NUM_31 = new VerbFrame(31, "Somebody ----s something with something");
        public static readonly VerbFrame NUM_32 = new VerbFrame(32, "Somebody ----s INFINITIVE");
        public static readonly VerbFrame NUM_33 = new VerbFrame(33, "Somebody ----s VERB-ing");
        public static readonly VerbFrame NUM_34 = new VerbFrame(34, "It ----s that CLAUSE");
        public static readonly VerbFrame NUM_35 = new VerbFrame(35, "Something ----s INFINITIVE");

        static VerbFrame()
        {
            LoadCache();
        }

        private static readonly Dictionary<int, VerbFrame> _cache = new Dictionary<int, VerbFrame>();
        private static void LoadCache()
        {
            FieldInfo[] fields = typeof(VerbFrame).GetFields(BindingFlags.Static | BindingFlags.Public);

            VerbFrame temp = null;
            for (int i = 0; i < fields.Length; i++)
            {

                if (fields[i].FieldType == typeof(VerbFrame))
                {
                    temp = fields[i].GetValue(null) as VerbFrame;
                    _cache.Add(temp.Number, temp);
                }
            }
        }
        
        public static IEnumerable<VerbFrame> Values()
        {
            return _cache.Values;
        }

        public static VerbFrame GetFrame(int number)
        {
            return _cache.ContainsKey(number) ? _cache[number] : null;
        }
        
        private readonly int _num;
        private readonly String _template;
       
        private VerbFrame(int num, String template)
        {
            _num = num;
            _template = template;
        }
        
        public int Number
        {
            get { return _num; }
        }

        public string Template
        {
            get { return _template; }
        }

        public string InstantiateTemplate(string verb)
        {
            if (verb == null)
                throw new ArgumentNullException();
            int index = _template.IndexOf("----");
            if (index == -1) return "";
            return _template.Substring(0, index) + verb + _template.Substring(index + 5, _template.Length);
        }

        public override string ToString()
        {
            return "[" + _num + " : " + _template + " ]";
        }
    }
}
